#ifndef ASTNODES_HPP
#define ASTNODES_HPP
#include<iostream>
#include<string>
#include"nfanode.h"
class RegularExpressionNode{
public:
    virtual void ConstructNFA(NFA_node*&,NFA_node*&)=0;
    virtual void printAST(int pad,std::ostream&out)=0;
};

class RegularExpressionNode_char : public RegularExpressionNode{
private:
    char ch;
public:
    RegularExpressionNode_char(char c):ch(c){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};

class RegularExpressionNode_or : public RegularExpressionNode{
private:
    RegularExpressionNode* exp1;
    RegularExpressionNode* exp2;
public:
    RegularExpressionNode_or(
        RegularExpressionNode* e1,
        RegularExpressionNode* e2
    ):exp1(e1),exp2(e2){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};

class RegularExpressionNode_concat : public RegularExpressionNode{
private:
    RegularExpressionNode* exp1;
    RegularExpressionNode* exp2;
public:
    RegularExpressionNode_concat(
        RegularExpressionNode* e1,
        RegularExpressionNode* e2
    ):exp1(e1),exp2(e2){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};

class RegularExpressionNode_star : public RegularExpressionNode{
private:
    RegularExpressionNode* exp;
public:
    RegularExpressionNode_star(
        RegularExpressionNode* e
    ):exp(e){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};

class RegularExpressionNode_paren : public RegularExpressionNode{
private:
    RegularExpressionNode* exp;
public:
    RegularExpressionNode_paren(
        RegularExpressionNode* e
    ):exp(e){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};

class RegularExpressionNode_null : public RegularExpressionNode{
private:
public:
    RegularExpressionNode_null(){}
    void ConstructNFA(NFA_node*&,NFA_node*&);
    void printAST(int pad,std::ostream&out);
};
#endif